We can just import two spring boot starters to easily build a project with shiro RBAC configuration and multi-datasources(also multi-dialects) configuration.
What we should do is to implemente the interface com.maxplus1.access.starter.config.shiro.rbac.service.IShiroService
and to edit the file application.yml
.
The starters depend on Druid
,Shiro
and MyBatis
.
写在前面
整合配置文件
|
|
Spring Bean装载过程
Spring装配Bean的过程
- 实例化;
- 设置属性值;
- 如果实现了BeanNameAware接口,调用setBeanName设置Bean的ID或者Name;
- 如果实现BeanFactoryAware接口,调用setBeanFactory 设置BeanFactory;
- 如果实现ApplicationContextAware,调用setApplicationContext设置ApplicationContext
- 调用BeanPostProcessor的预先初始化方法;
- 调用InitializingBean的afterPropertiesSet()方法;
- 调用定制init-method方法;
- 调用BeanPostProcessor的后初始化方法;
Spring容器关闭过程
- 调用DisposableBean的destroy();
- 调用定制的destroy-method方法;
Spring Boot SPI
Spring Boot SPI 可以代替包扫描的配置
Spring Boot SPI 类似于 Java SPI的加载机制。
META-INF/spring.factories配置:
BeanPostProcessor
- BeanPostProcessor包含了InitializingBean的前后拦截器
Spring的监听器
了解一下Spring Boot监听器的生命周期,更具体的可以去看官方文档。
flyway
数据库迁移工具:flyway支持。flyway企业版才支持Oracle 11。
可以尝试回退到4.2.0版本。flayway的思路是最新版本免费支持最新的Oracle~
在使用oracle的时候,如果报莫名错误,尝试如下sql:
整合问题
我调试的过程和此文类似,就是为了搞清楚BeanPostProcessor
的调用顺序。
详情点击
于是我在内部类DruidDataSourceConfiguration.DruidDataSourceBeanPostProcessor
中,让DruidDataSourceBeanPostProcessor实现了PriorityOrdered
接口,
让数据源可以优先处理。
否则,在整合我的2个自定义starter,Shiro和MyBatis造成冲突。(复杂的依赖关系)
报错如下:
调试也可以发现,没有进入DruidDataSourceBeanPostProcessor,Spring的自动装配顺序有点让人意外。
其中到底是Shiro Starter的哪个依赖提前加载了DataSource,影响了DruidDataSourceBeanPostProcessor,我已无法理清……
(头晕眼花的debug= =||,偷个懒,不调试了……)
mybatis-spring-boot-starter
- pagination & druid & mybatis for multi datasources(event different dialects),all in one strarter~
- 此工具通过一个starter直接开启多数据源(支持不同方言)的druid+mybatis+分页的工程,非常方便于复用~
- 写了大量的BeanDefinition,可能有缺少的属性。
如果@Bean可以一次性返回多个Bean并且注册到Spring容器,
则可以作出大量简化,并复用大量的starter。
比如:123456public Map<String,Bean> manyBeans(){Map<String,Bean> beans = new HashMap<>();// 分别设置BeanName和Beanreturn beans;}
详情看我提的 :
注意
- 所有的bean,比如
PageInterceptor
、DruidDataSource
、SqlSessionFactory
、TransactionManager
等,所有注入的BeanName都是:数据源+类名。例如:xxxTransactionManager
,xxx
表示数据源的名字 - 但是
xxxTransactionManager
起了别名xxx
,方便处理事务。用于@Transactional('xxx')
PS
- 基本遵循mybatis-spring-boot-starter和druid-spring-boot-starter的配置格式
- 如果存在不支持属性,欢迎提issue
shiro-spring-boot-starter
- it is easy to use shiro for rest api ~ quick start ~ base on spring boot 2.x
- 此starter封装并不只是为了使用完整的Shiro功能,目的是为大家提供一种封装思路,如果实际应用在业务场景,还需要具体情况具体分析
- 当然你也可以遵循目前的设计规范,如果有功能没有满足,不妨提个issue……
- 倘若你有自己的设计,fork过去尽情修改吧~
JWT和Session的区别
- JWT:服务端无状态。所有状态存储在客户端的加密token里面。服务端只负责校验token的有效性。服务端无法强制下线。
- Session:服务端有状态。客户端只是存储一个sid,服务端存储sid对应的信息。多应用共享Session通常使用Redis之类的内存数据库存储。
登录鉴权方式
- 使用传统的session方式
SessionId传递
- sessionId放在header或者cookie进行传递。header的sid具有高优先级。
Session的序列化
- 由于Session都会实现Serializable,所以统一使用JDK的序列化方式,保证稳定性和兼容性。
Redis配置
- Redis配置完全和spring-data-redis一致,且为默认的RedisTemplate
- 由于Shiro的序列化方式默认是JDK序列化,如果非Shiro需要使用其他序列化方式,需要单独配置,参考demo-redis。
- 多Redis数据源配置:此时
spring.redis
的配置依然需要配置,其他数据源单独配置。
appId
- appId用于多系统交互时使用,如果系统不涉及此方面,可以忽略。
- appId可以通过配置文件配置,表示当前系统的app标识
- 也可以遵循协议,appId通过cookie或者header传递。header具有较高优先级(设计和Session一样)
- 为什么不放在Session?
- 因为多系统可能公用一个Session,此时无法判断当前Session属于哪个系统。
配置文件示例
|
|
Filters与AuthorizingAnnotationMethodInterceptor
@RequiresPermissions
注解的处理是通过AOP实现拦截器PermissionAnnotationMethodInterceptor
来处理;而perms
是通过filter来实现的:PermissionsAuthorizationFilter
。- Filter与MethodInterceptor的区别,Filter是基于URL做的拦截,而MethodInterceptor是基于AOP直接对方法进行的拦截。对于REST URL,比如
/api/user/{id}
这样的url请求。 - Filter处理REST URL需要自己实现Filter并对url进行解析匹配(具体参考spring mvc的url匹配规则,略复杂);或者直接使用MethodInterceptor。
demo测试
- 启动demo or demo-redis
- 登录测试(返回SessionId):127.0.0.1:9000/demo/api/sys/login?userName=yonghu0&password=PASS0
- 访问测试(需要在cookie或者header带上uuusid=sessionId访问):127.0.0.1:9000/demo/api/sys/testAccess
- 无权限访问测试(需要在cookie或者header带上uuusid=sessionId访问):127.0.0.1:9000/demo/api/sys/testDeny
- 测试不同的Redis序列化方式:127.0.0.1:9000/demo/api/sys/testRedis
HTTP状态码
- 未登录被拒绝:401
- 未授权被拒绝:403
注意
- 既然基于Shiro做了封装,那么可自定义的模块肯定减少,如果需要增加其他配置。可以:
- 下载源码自行修改
- 提issue到github
- 使用原生Shiro进行个性化的封装
com.maxplus1.access.starter.config.shiro.interceptor.shiro.Perms
(已废弃)- 此包只适配了前后端分离的项目,没有对静态资源进行处理。且Shiro的异常以json形式返回。
deploy
- 更改parent下的pom.xml的
deploy2maven.url.snapshots
和deploy2maven.url.releases
为自己私库的url 配置maven的settings.xml的server标签。如下:
12345678910<server><id>user-snapshot</id><username>your name</username><password>your pass</password></server><server><id>user-release</id><username>your name</username><password>your pass</password></server>执行maven的deploy命令
TODO
- Session的一级缓存,二级缓存
- 动态更新权限,刷新缓存
- 同一账号多处登录问题
- 账户踢出接口
- Shiro其他配置